home *** CD-ROM | disk | FTP | other *** search
- /* Scroll.c
- * Handle window scrolling in Writeswell, Jr.
- * ©1992 Working Software, Inc.
- * This source code is copyrighted. Permission is granted to use the Word Services
- * portion of the Writeswell Jr. source code in your own programs, but you
- * may not distribute the Writeswell Jr. word-processor code as a
- * commercial product. If you modify the code, please do not call it
- * Writeswell Jr. (or Writeswell.) This will ensure that people understand the
- * program and don’t have to deal with a number of different versions with
- * who-knows-what going on in the code.
- *
- * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
- * 18 Apr 92 Mike Crawford
- */
-
- #include <EPPC.h>
- #include <AppleEvents.h>
- #include <AEObjects.h>
- #include "AERegistry.h"
- #include "TBConstants.h"
- #include "TBGlobals.h"
- #include "Scroll.h"
- #include "TTPictures.h"
-
- void DoControl( WindowPtr theWindow, ControlHandle ctlHdl, short partCode, Point where )
- {
- short oldVal;
- short newVal;
- ControlActionUPP trackProcUPP;
-
- gScrollWindow = theWindow;
-
- switch ( partCode ){
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
-
- trackProcUPP = NewControlActionProc( TrackScrollBar );
- if ( !trackProcUPP )
- return; // STUB Should report an error
-
- TrackControl( ctlHdl, where, trackProcUPP );
-
- #ifdef GENERATINGCFM
- DisposeRoutineDescriptor( trackProcUPP );
- #endif
-
- break;
- case inThumb:
- oldVal = GetCtlValue( ctlHdl );
- TrackControl( ctlHdl, where, (ControlActionUPP)NULL );
- newVal = GetCtlValue( ctlHdl );
-
- if ( newVal != oldVal ){
- ScrollText( oldVal, newVal, ctlHdl );
- }
-
- break;
- }
-
- return;
- }
-
- pascal void TrackScrollBar( ControlHandle ctlHdl, short partCode )
- {
- short max;
- short min;
- short val;
- short newVal;
-
- max = GetCtlMax( ctlHdl );
- min = GetCtlMin( ctlHdl );
- val = GetCtlValue( ctlHdl );
- newVal = val;
-
- switch ( partCode ){
- case inUpButton:
- if ( val > min )
- newVal = val - 1;
- break;
- case inDownButton:
- if ( val < max )
- newVal = val + 1;
- break;
- case inPageUp:
- newVal = val - gLinesPerPage;
-
- if ( newVal < min )
- newVal = min;
- break;
-
- case inPageDown:
- newVal = val + gLinesPerPage;
-
- if ( newVal > max )
- newVal = max;
- break;
- }
-
- if ( newVal != val ){
- ScrollText( val, newVal, ctlHdl );
- }
-
- return;
- }
-
- void ScrollText( short oldVal, short newVal, ControlHandle ctlHdl )
- {
- TEHandle textH;
- short dV;
-
- SetCtlValue( ctlHdl, newVal );
-
- textH = (TEHandle)GetWRefCon( gScrollWindow );
-
- /* 1.0d15 Styled TextEdit requires that we use TEGetHeight to get the height
- * of the actual line, since it is variable. Under STE, lineHeight is -1.
- *
- * Also, TEGetHeight includes the height of both lines... If we are measuring
- * the height of line 2, we want to do TEGetHeight( 2, 2, textH ). We need to
- * check for cases of going up and going down. If we are at the top, though,
- * we want to do TEGetHeight( 0, 1, textH )
- */
-
- if ( newVal > oldVal ){
- /* We're scrolling towards the bottom of the text */
-
- if ( oldVal != 0 ){
- newVal--;
- }
- dV = -TEGetHeight( oldVal, newVal, textH );
- }else{
- /* We're scrolling towards the top of the text */
- /* STUB not sure if I gotta check if we're at the bottom */
-
- if ( oldVal != 0 ){
- newVal++;
- }
- dV = TEGetHeight( oldVal, newVal, textH );
- }
-
- #ifdef NEVER
- dV = ( oldVal - newVal ) * (*textH)->lineHeight;
- #endif
-
- TEScroll( 0, dV, textH );
-
- ScrollPictures( dV, textH );
-
- return;
- }
-
- Boolean TrackContentClick( void )
- {
- Point where;
- Rect viewRect;
- TEHandle textH;
- ControlHandle ctlHdl;
- GrafPtr curPort;
- RgnHandle oldClip;
- Rect scrollRect;
- Boolean needRedraw;
-
- /* Track the mouse while it is clicked in the window, and scroll the textEdit
- * field if necessary. We must always return true. We have to set the port
- * so that GetMouse will have the right window's local coordinates.
- */
-
- GetPort( &curPort );
- SetPort( gScrollWindow );
-
- GetMouse( &where );
-
- textH = (TEHandle)GetWRefCon( gScrollWindow );
-
- viewRect = (*textH)->viewRect;
-
- ctlHdl = ((WindowPeek)gScrollWindow)->controlList; /* We know there's 1 control */
-
- needRedraw = false;
-
- /* If the mouse is above or below the window, we fake a mouse click on the scroll bar */
- if ( where.v < viewRect.top ){
- TrackScrollBar( ctlHdl, inUpButton );
- needRedraw = true;
- } else if ( where.v > viewRect.bottom ){
- TrackScrollBar( ctlHdl, inDownButton );
- needRedraw = true;
- }
-
- /* We need to redraw the control so that the user can see the thumb move.
- * This involved setting the clip region to include scroll bar.
- */
-
- if ( needRedraw ){
- oldClip = NewRgn();
- if ( oldClip ){
- GetClip( oldClip );
- scrollRect = (*ctlHdl)->contrlRect;
- ClipRect( &scrollRect );
- Draw1Control( ctlHdl );
- SetClip( oldClip );
- DisposeRgn( oldClip );
- }
- }
-
- SetPort( curPort );
-
- return true;
- }
-
- void SizeVertScroll()
- {
- // MoveControl( gVertScroll, (short) (&qd.thePort->portRect.right - 15), -1 );
- // SizeControl( gVertScroll, 16, (short) (&qd.thePort->portRect.bottom - &qd.thePort->portRect.top - 13) );
-
- MoveControl( gVertScroll, (short) ( qd.thePort->portRect.right - 15), -1 );
- SizeControl( gVertScroll, 16, (short) ( qd.thePort->portRect.bottom - qd.thePort->portRect.top - 13) );
-
- return;
- }
-
- void SetVertScroll( WindowPtr theWindow, ControlHandle scrollHdl )
- {
- short totalHeight;
- short viewHeight;
- TEHandle hTE;
- Rect viewRect;
- Rect destRect;
- short nLines;
- short tweenHeight;
- short i;
- short scrollAmt;
- short offSet;
-
- /* The limits of the scroll bar range from 0 to the first line of the last
- * "windowfull" of text. That is, if there are 50 lines of text, and 10 lines
- * would fit in the window, then the limits are 0 through 40. If the window is
- * resized so that 20 lines of text would fit, then the limits are 0 and 30. This
- * way, when the thumb is all the way at the bottom, the last line of text is at
- * the bottom of the window.
- */
-
- hTE = (TEHandle)GetWRefCon( theWindow );
-
- nLines = (*hTE)->nLines;
-
- totalHeight = TEGetHeight( 0, nLines - 1, hTE );
-
- viewRect = (*hTE)->viewRect;
- destRect = (*hTE)->destRect;
-
- viewHeight = viewRect.bottom - viewRect.top;
-
- /* if the last line of text does not fall at or below the bottom of the window,
- * scroll the text down so it does, but not so much that the top line of text is
- * lower than the top of the window.
- */
-
- offSet = viewRect.top - destRect.top;
-
- if ( totalHeight >= viewHeight && ( totalHeight - offSet < viewRect.bottom ) ){
- scrollAmt = -( totalHeight - offSet - viewRect.bottom );
- scrollAmt -= TEGetHeight( nLines, nLines, hTE );
- TEScroll( 0, scrollAmt, hTE );
- viewRect = (*hTE)->viewRect;
- viewHeight = viewRect.bottom - viewRect.top;
- destRect = (*hTE)->destRect;
- }
-
- if ( totalHeight < viewHeight ){
-
- /* All of the text will fit in the window. Scroll the text so the first
- * line is at the top, and turn off the scroll bar.
- */
-
- scrollAmt = viewRect.top - (*hTE)->destRect.top;
- TEScroll( 0, scrollAmt, hTE );
-
- HiliteControl( scrollHdl, 255 );
-
- return;
- }
-
- /* The text does not all fit. Find out how many lines from the bottom would fit */
-
- for ( i = nLines - 1; i > 0; i-- ){
- tweenHeight = TEGetHeight( nLines, i, hTE );
-
- if ( tweenHeight >= viewHeight )
- break;
- }
-
- /* i is now the line number of the first line that would be in the window if
- * we had scrolled all the way to the bottom
- */
-
- SetCtlMax( scrollHdl, i - 1 );
-
- /* Save the number of lines on a page for later use by scroll bar tracker */
-
- gLinesPerPage = nLines - i;
-
- for ( i = 1; i < nLines; i++ ){
- tweenHeight = TEGetHeight( 1, i, hTE );
-
- if ( tweenHeight > viewRect.top - destRect.top )
- break;
- }
-
- /* i is now the line number of the first line in the window
- */
-
- SetCtlValue( scrollHdl, i );
-
- HiliteControl( scrollHdl, 0 );
-
-
- return;
- }
-
- void ShowSelection( TEHandle hTE )
- {
- short i;
- short scrollAmt;
- short linesInRect;
- short selStart;
- short viewHeight;
- Rect viewRect;
- Rect destRect;
- short nLines;
- short lineHeight;
- short totalHeight;
- short offset;
-
- selStart = (*hTE)->selStart;
-
- viewRect = (*hTE)->viewRect;
- destRect = (*hTE)->destRect;
-
- offset = viewRect.top - destRect.top;
-
- nLines = (*hTE)->nLines;
- /*totalHeight = TEGetHeight( 0, nLines - 1, hTE );*/
-
- /* scroll as needed to desired line */
- i= 0;
-
- while( i < nLines && (selStart >= ((*hTE)->lineStarts[i])))
- i++;
-
- viewHeight = viewRect.bottom - viewRect.top;
-
- lineHeight = TEGetHeight( 1, i, hTE );
-
- if ( lineHeight - offset > viewRect.bottom ){
-
- scrollAmt = (lineHeight - viewRect.bottom - offset) + viewHeight / 2;
-
-
- }else if ( lineHeight - offset < viewRect.top ){
-
- /* 1.0.3 MDC I didn't have offset here before - it screwed up
- * when you moved off the top with the cursor keys
- */
-
- scrollAmt = -( (viewRect.top + offset - lineHeight ) + viewHeight / 2 );
-
- if ( scrollAmt < -offset )
- scrollAmt = -offset; /* Limit scrolling so we don't go past top */
- }else
- return;
-
-
- TEScroll(0,-scrollAmt,hTE);
-
- ScrollPictures( -scrollAmt, hTE );
-
- return;
- }